<?php
class YHtml extends CHtml{
	
	
	public static function tag($tag,$htmlOptions=array(),$content=false,$closeTag=true){
		if(is_array($htmlOptions) && isset($htmlOptions['visible'])){
			if($htmlOptions['visible']){
				unset($htmlOptions['visible']);
			}else{
				return '';
			}
		}
		return parent::tag($tag, $htmlOptions, $content, $closeTag);
	}
	
	public static function link($text, $url='#', $htmlOptions=array()){
		if($url!=='')
			$htmlOptions['href']=self::normalizeUrl($url);
		self::clientChange('click', $htmlOptions);
		return self::tag('a',$htmlOptions,$text);
	}
	
	public static function button($label='button',$htmlOptions=array()){
		if(!isset($htmlOptions['name'])){
			if(!array_key_exists('name',$htmlOptions))
				$htmlOptions['name']=self::ID_PREFIX.self::$count++;
		}
		if(!isset($htmlOptions['type']))
			$htmlOptions['type']='button';
		if(!isset($htmlOptions['value']))
			$htmlOptions['value']=$label;
		self::clientChange('click',$htmlOptions);
		return self::tag('input',$htmlOptions);
	}
	
	public static function checkBoxList($name,$select,$data,$htmlOptions=array())
	{
		$template=isset($htmlOptions['template'])?$htmlOptions['template']:'{input} {label}';
		$separator=isset($htmlOptions['separator'])?$htmlOptions['separator']:"<br/>\n";
		unset($htmlOptions['template'],$htmlOptions['separator']);
	
		if(substr($name,-2)!=='[]')
			$name.='[]';
	
		if(isset($htmlOptions['checkAll']))
		{
			$checkAllLabel=$htmlOptions['checkAll'];
			$checkAllLast=isset($htmlOptions['checkAllLast']) && $htmlOptions['checkAllLast'];
		}
		unset($htmlOptions['checkAll'],$htmlOptions['checkAllLast']);
	
		$labelOptions=isset($htmlOptions['labelOptions'])?$htmlOptions['labelOptions']:array();
		unset($htmlOptions['labelOptions']);
	
		$items=array();
		$baseID=self::getIdByName($name);
		$id=0;
		$checkAll=true;
	
		foreach($data as $value=>$label)
		{
			$checked=!is_array($select) && !strcmp($value,$select) || is_array($select) && in_array($value,$select);
			$checkAll=$checkAll && $checked;
			$htmlOptions['value']=$value;
			$htmlOptions['id']=$baseID.'_'.$id++;
			$option=self::checkBox($name,$checked,$htmlOptions);
			$label=self::label($label,$htmlOptions['id'],$labelOptions);
			$items[]=strtr($template,array('{input}'=>$option,'{label}'=>$label));
		}
	
		if(isset($checkAllLabel))
		{
			$htmlOptions['value']=1;
			$htmlOptions['id']=$id=$baseID.'_all';
			$option=self::checkBox($id,$checkAll,$htmlOptions);
			$label=self::label($checkAllLabel,$id,$labelOptions);
			$item=strtr($template,array('{input}'=>$option,'{label}'=>$label));
			if($checkAllLast)
				$items[]=$item;
			else
				array_unshift($items,$item);
			$name=strtr($name,array('['=>'\\[',']'=>'\\]'));
			$js=<<<EOD
$('#$id').click(function() {
	$("input[name='$name']").prop('checked', this.checked);
});
$("input[name='$name']").click(function() {
	$('#$id').prop('checked', !$("input[name='$name']:not(:checked)").length);
});
$('#$id').prop('checked', !$("input[name='$name']:not(:checked)").length);
EOD;
			$cs=Yii::app()->getClientScript();
			$cs->registerCoreScript('jquery');
			$cs->registerScript($id,$js);
		}
	
		return self::tag('span',array('id'=>$baseID),implode($separator,$items));
	}
	
	
	public static function submitButton($label='submit',$htmlOptions=array())
	{
		$htmlOptions['type']='submit';
		return self::button($label,$htmlOptions);
	}
	
	public static function image($src,$alt='',$htmlOptions=array())
	{
		$htmlOptions['src']=$src;
		$htmlOptions['alt']=$alt;
		return self::tag('img',$htmlOptions);
	}
	
	public static function encode($text){
		return htmlspecialchars($text,ENT_QUOTES,Yii::app()->charset);
	}
	

	public static function activeDateField($model,$attribute,$htmlOptions=array()){
		self::resolveNameID($model,$attribute,$htmlOptions);
		self::clientChange('change',$htmlOptions);
		return self::activeInputField('date',$model,$attribute,$htmlOptions);
	}
	
	public static function activeRadioButton($model,$attribute,$htmlOptions=array()){
		self::resolveNameID($model,$attribute,$htmlOptions);
		if(!isset($htmlOptions['value']))
			$htmlOptions['value']=1;
		if(!isset($htmlOptions['checked']) && self::resolveValue($model,$attribute)==$htmlOptions['value'])
			$htmlOptions['checked']='checked';
		self::clientChange('click',$htmlOptions);
	
		if(array_key_exists('uncheckValue',$htmlOptions))
		{
			$uncheck=$htmlOptions['uncheckValue'];
			unset($htmlOptions['uncheckValue']);
		}
		else
			$uncheck='0';
	
		$hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
		$hidden=$uncheck!==null ? self::hiddenField($htmlOptions['name'],$uncheck,$hiddenOptions) : '';
	
		// add a hidden field so that if the radio button is not selected, it still submits a value
		return $hidden . self::activeInputField('radio',$model,$attribute,$htmlOptions);
	}
	
	public static function activeFileField($model,$attribute,$htmlOptions=array())
	{
		self::resolveNameID($model,$attribute,$htmlOptions);
		// add a hidden field so that if a model only has a file field, we can
		// still use isset($_POST[$modelClass]) to detect if the input is submitted
		$hiddenOptions=isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
		return self::hiddenField($htmlOptions['name'],'',$hiddenOptions)
		. self::activeInputField('file',$model,$attribute,$htmlOptions);
	}
	
	public static function activeHiddenField($model,$attribute,$htmlOptions=array()){
		if(is_array($model)){
			return self::activeInputField('hidden', $model, $attribute, $htmlOptions);
		}else{
			return parent::activeHiddenField($model, $attribute, $htmlOptions);
		}
	}
	
	public static function htmlButton($label='button',$htmlOptions=array())
	{
		if(!isset($htmlOptions['name']))
			$htmlOptions['name']=self::ID_PREFIX.self::$count++;
		if(!isset($htmlOptions['type']))
			$htmlOptions['type']='button';
		self::clientChange('click',$htmlOptions);
		return self::tag('button',$htmlOptions,$label);
	}
	
	public static function textField($name,$value='',$htmlOptions=array())
	{
		self::clientChange('change',$htmlOptions);
		return self::inputField('text',$name,$value,$htmlOptions);
	}
	
	public static function hiddenField($name,$value='',$htmlOptions=array())
	{
		return self::inputField('hidden',$name,$value,$htmlOptions);
	}
	
	public static function activeTextArea($model,$attribute,$htmlOptions=array())
	{
		self::resolveNameID($model,$attribute,$htmlOptions);
		self::clientChange('change',$htmlOptions);
		if(!is_array($model)){
			if($model->hasErrors($attribute))
				self::addErrorCss($htmlOptions);
		}
		$text=self::resolveValue($model,$attribute);
		return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $text : self::encode($text));
	}
	
    public static function dropDownList($name,$select,$data,$htmlOptions=array())
	{
		$htmlOptions['name']=$name;
		if(!isset($htmlOptions['id']))
			$htmlOptions['id']=self::getIdByName($name);
		else if($htmlOptions['id']===false)
			unset($htmlOptions['id']);
		self::clientChange('change',$htmlOptions);
		$options="\n".self::listOptions($select,$data,$htmlOptions);
		return self::tag('select',$htmlOptions,$options);
	}
	
	public static function textArea($name,$value='',$htmlOptions=array())
	{
		$htmlOptions['name']=$name;
		if(!isset($htmlOptions['id']))
			$htmlOptions['id']=self::getIdByName($name);
		else if($htmlOptions['id']===false)
			unset($htmlOptions['id']);
		self::clientChange('change',$htmlOptions);
		return self::tag('textarea',$htmlOptions,isset($htmlOptions['encode']) && !$htmlOptions['encode'] ? $value : self::encode($value));
	}
	
	public static function label($label,$for,$htmlOptions=array())
	{
		if($for===false)
			unset($htmlOptions['for']);
		else
			$htmlOptions['for']=$for;
		if(isset($htmlOptions['required']))
		{
			if($htmlOptions['required'])
			{
				if(isset($htmlOptions['class']))
					$htmlOptions['class'].=' '.self::$requiredCss;
				else
					$htmlOptions['class']=self::$requiredCss;
				$label=self::$beforeRequiredLabel.$label.self::$afterRequiredLabel;
			}
			unset($htmlOptions['required']);
		}
		return self::tag('label',$htmlOptions,$label);
	}
	
	public static function activeDropDownList($model,$attribute,$data,$htmlOptions=array()){
		self::resolveNameID($model, $attribute, $htmlOptions);
		$selection=self::resolveValue($model, $attribute);
		$options="\n".self::listOptions($selection, $data, $htmlOptions);
		self::clientChange('change',$htmlOptions);
		if(!is_array($model)){
			if($model->hasErrors($attribute))
				self::addErrorCss($htmlOptions);
		}
		
		if(isset($htmlOptions['multiple'])){
			if(substr($htmlOptions['name'],-2)!=='[]')
				$htmlOptions['name'].='[]';
		}
		return self::tag('select',$htmlOptions,$options);
	}
	
	public static function activeTextField($model, $attribute, $htmlOptions = array()){
		if(is_array($model)){
			return self::activeInputField('text', $model, $attribute, $htmlOptions);
		}else{
			return parent::activeTextField($model, $attribute, $htmlOptions);
		}
	}
	
	public static function activeCheckBox($model,$attribute,$htmlOptions=array()){
		self::resolveNameID($model, $attribute, $htmlOptions);
		if(!isset($htmlOptions['value']))
			$htmlOptions['value']=1;
		if(!isset($htmlOptions['checked']) && self::resolveValue($model,$attribute)==$htmlOptions['value'])
			$htmlOptions['checked'] = 'checked';
		self::clientChange('click', $htmlOptions);
	
		if(array_key_exists('uncheckValue',$htmlOptions)){
			$uncheck = $htmlOptions['uncheckValue'];
			unset($htmlOptions['uncheckValue']);
		}else{
			$uncheck='0';
		}
	
		$hiddenOptions = isset($htmlOptions['id']) ? array('id'=>self::ID_PREFIX.$htmlOptions['id']) : array('id'=>false);
		$hidden = $uncheck !== null ? self::hiddenField($htmlOptions['name'], $uncheck,$hiddenOptions) : '';
	
		return $hidden . self::activeInputField('checkbox', $model, $attribute, $htmlOptions);
	}
	
	protected static function activeInputField($type, $model, $attribute, $htmlOptions){
		$htmlOptions['type'] = $type;
	
		self::resolveNameID($model, $attribute, $htmlOptions);
		
		if($type==='file'){
			unset($htmlOptions['value']);
		}else if(!isset($htmlOptions['value'])){
			$htmlOptions['value'] = self::resolveValue($model, $attribute);
		}

		return self::tag('input', $htmlOptions);
	}

	public static function resolveValue($model, $attribute){
		if(is_array($model)){
			if(($pos = strpos($attribute,'['))!==false){
				if($pos===0){
					if(preg_match('/\](\w+)/',$attribute,$matches))
						$attribute=$matches[1];
					if(($pos=strpos($attribute,'['))===false)
						return $model[$attribute];
				}
				$name=substr($attribute,0,$pos);
				$value = $model[$name];
				foreach(explode('][',rtrim(substr($attribute,$pos+1),']')) as $id){
					if(is_array($value) && isset($value[$id]))
						$value = $value[$id];
					else
						return null;
				}
				return $value;
			}else{
				if(isset($model[$attribute]))
					return $model[$attribute];
				else
					return null;
			}
		}else{
			return parent::resolveValue($model, $attribute);
		}
	}
	
	public static function resolveNameID($model, &$attribute, &$htmlOptions){
		if(is_array($model)){
			if(!isset($htmlOptions['name'])){
				$htmlOptions['name'] = $attribute;
				if(isset($htmlOptions['model'])){
					$htmlOptions['name'] = $htmlOptions['model'] . '[' . $htmlOptions['name'] . ']';
					unset($htmlOptions['model']);
				}
			}
			
			if(!isset($htmlOptions['id'])){
				$htmlOptions['id'] = preg_replace('/\[(.*)\]/', '_$1', $htmlOptions['name']);
			}
		}
		return parent::resolveNameID($model, $attribute, $htmlOptions);
	}
}

?>